#include "mystdio.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#define DFL_MODE 0666

extern myFILE* my_fopen(const char* path,const char *mode)
{
    int fd = 0;
    int flag = 0;
    if(strcmp(mode,"r")==0)
    {
        flag |= (O_RDONLY);

    }
    else if(strcmp(mode,"w") == 0)
    {
        flag |= (O_WRONLY|O_CREAT|O_TRUNC);
    }
    else if(strcmp(mode,"a") == 0)
    {
        flag |= (O_WRONLY|O_CREAT|O_APPEND);
    }
    else 
    {
        //do nothing
    }

    if(flag & O_CREAT) //需要创建
    {
        fd = open(path,flag, DFL_MODE);

    }
    else 
    {
        fd = open(path,flag);
    }

    if(fd < 0)
    {
        errno = 2;
        return NULL;
    }
    myFILE* fp = (myFILE*)malloc(sizeof(myFILE));
    if(fp == NULL)
    {
        errno = 3;
        return NULL;
    }
    fp->flag = FLUSH_LINE;//缓冲区采用行刷新
    fp->end = 0;//缓冲区没有东西
    fp->fileno = fd;
    return fp;
}
extern int my_fwrite(const char* s, int num, myFILE* stream)//num从s中写入num个
{
    //写入的实质是把数据放到缓冲区中
    memcpy(stream->buffer + stream->end,s,num);//拷贝到缓冲区,没有拷贝'\0'
    stream->end += num;
    
    //判断是否需要刷新
    if((stream->flag & FLUSH_LINE) && stream->end > 0 && stream->buffer[stream->end-1 == '\n']) 
    {
        //有bug "ab\ncd"不刷新
        my_fflush(stream);
    }

    return stream->end;
}
extern int my_fflush(myFILE* stream) 
{
    if(stream->end > 0) 
    {
        write(stream->fileno,stream->buffer,stream->end);
        //fsync(stream->fileno)//把数据从操作系统刷新到内核，不关心
        stream->end = 0;
    }
    //刷新本质是c语言缓冲区的内容给操作系统中对应的fd
    return 0;
}
extern int my_fclose(myFILE* stream)
{
    //不能直接关闭，要先把缓冲区刷新
    my_fflush(stream);
    return close(stream->fileno);
    
}


